package com.zl.common.utils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonGenerator.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.zl.common.annotaion.TruncatedContent;

/**
 * 
 * @author zhouliang
 *
 */
public abstract class JsonUtil {

    /**
     * The Constant LOGGER.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(JsonUtil.class);

    /**
     * The object mapper.
     */
    private static ObjectMapper objectMapper = new ObjectMapper();
    private static ObjectMapper objectMapper2 = new ObjectMapper();

    static {
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.setSerializationInclusion(Include.NON_NULL);
        objectMapper.configure(Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        
        objectMapper2.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper2.setSerializationInclusion(Include.NON_NULL);
        objectMapper2.configure(Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
        objectMapper2.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 启用自定义注解功能
        objectMapper2.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
            private static final long serialVersionUID = 1L;
            @Override
            public Object findSerializer(Annotated annotated) {
                if (annotated.hasAnnotation(TruncatedContent.class)) {
                    TruncatedContent jsonProperty = annotated.getAnnotation(TruncatedContent.class);
                    return new TruncatedStringSerializer(jsonProperty.length());
                    
                }
                return super.findSerializer(annotated);
            }
        });
    }
    static class TruncatedStringSerializer extends JsonSerializer<String> {
        private int MAX_LENGTH = 500;
        public TruncatedStringSerializer(){
        }
        public TruncatedStringSerializer(int length) {
            this.MAX_LENGTH = length;
        }
        @Override
        public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
            if (value.length() > MAX_LENGTH) {
                gen.writeString(value.substring(0, MAX_LENGTH) + "...");
            } else {
                gen.writeString(value);
            }
        }
    }
    public static ObjectMapper objectMapper2(Object object) {
    	return objectMapper2;
    }
    /**
     * Convert to json.
     *
     * @param object the object
     * @return the string
     */
    public static String convertToJson2(Object object) {
        try {
            return objectMapper2.writeValueAsString(object);
        } catch (Exception e) {
            LOGGER.error("convert failed", e);
            return "";
        }
    }
    
    /**
     * Convert to json.
     *
     * @param object the object
     * @return the string
     */
    public static String convertToJson(Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            LOGGER.error("convert failed", e);
            return "";
        }
    }

    public static <T> T json2Bean(String json, Class<T> T) {
        try {
            T obj = objectMapper.readValue(json, T);
            return obj;
        } catch (Exception e) {
            LOGGER.error("convert failed", e);
            return null;
        }
    }

    public static <T> T json2Bean(String json, JavaType T) {
        try {
            T obj = objectMapper.readValue(json, T);
            return obj;
        } catch (Exception e) {
            LOGGER.error("convert failed", e);
            return null;
        }
    }

    public static <T> List<T> json2List(String json, Class<T> T) {
        JavaType javaType = getCollectionType(ArrayList.class, T);
        List<T> lst;
        try {
            lst = objectMapper.readValue(json, javaType);
        } catch (Exception e) {
            LOGGER.error("convert failed", e);
            return null;
        }
        return lst;
    }

    /**
     * 获取泛型的Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses  元素类
     * @return JavaType Java类型
     * @since 1.0
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }
}